package com.ctrip.corp.obt.shard.infrastructure.etcd;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.ctrip.corp.obt.generic.etcd.IConfigCenter;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.shard.core.ShardDataSource;
import com.ctrip.corp.obt.shard.domain.gateway.DataShardSourceGateway;

import io.grpc.StatusRuntimeException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author marco.zheng
 * @version 1.0
 * @date 2022/03/15
 * @desc etcd 数据网关
 * @see
 * @since 1.0
 */
@Slf4j
@RequiredArgsConstructor
public class EtcdDataShardSourceGateway implements DataShardSourceGateway {

    private final IConfigCenter configCenter;

    @Override
    public Set<ShardDataSource> getAllSource() {
        List<EtcdShardSource> etcdDataSourceList = getEtcdShardSourceModels();
        if (CollectionUtils.isEmpty(etcdDataSourceList)) {
            return Collections.emptySet();
        }
        // List<EtcdTenantModel> tenantList = configCenter.getPrefix("/data_shard/tenant/", EtcdTenantModel.class);
        // Map<String, EtcdTenantModel> tenantModelMap =
        // tenantList.stream().collect(Collectors.toMap(EtcdTenantModel::getId, Function.identity()));

        // 加载etcd数据源
        return etcdDataSourceList.stream().map(ShardDataSource::build).collect(Collectors.toSet());
    }

    @Override
    public Set<ShardDataSource> getSourceByTenantIds(Set<String> tenantIds) {
        List<EtcdShardSource> etcdDataSourceList = getEtcdShardSourceModels();
        if (CollectionUtils.isEmpty(etcdDataSourceList)) {
            return Collections.emptySet();
        }
        return etcdDataSourceList.stream().filter(dataShardSource -> tenantIds.contains(dataShardSource.getTenantId()))
            .map(ShardDataSource::build).collect(Collectors.toSet());
    }

    /**
     * 从arch-platform中获取已配置的数据源
     * 
     * @return
     */
    private List<EtcdShardSource> getEtcdShardSourceModels() {
        try {
            if (configCenter == null) {
                return Collections.emptyList();
            }
            return configCenter.getPrefix("/data_shard/shard_source/", EtcdShardSource.class);
        } catch (StatusRuntimeException ex) {
            log.info("Skip etcd shard source loading per connection is invalid");
        } catch (Exception ex) {
            log.error("Etcd shard source loading got error: {}", ex.getMessage());
        }
        return Collections.emptyList();
    }

}
